/*
	MIDAS Context Based Routing
	cbr_context_model.h
	Copyright (c) 2007 Radoslaw Olgierd Schoeneich
	MEAG IT PW
*/

#ifndef cbr_context_model_h_
#define cbr_context_model_h_

#include <string>
//#include <istream>
#include <map>
#include <utility>
#include <set>
#include "cbr_types.h"
#include "cbr_address.h"

/**
 * Context Model.
 */

template<typename T>
class cbr_Matrix;

class cbr_ContextModel : private cbr_Object {
private:
	int num_concepts;
	std::string* concepts;

	typedef std::less<std::string> less_fn;
	typedef std::map<std::string, int, less_fn> concepts_map_t;
	concepts_map_t concepts_map;

	cbr_Matrix<int>* concepts_graph;

	cbr_Matrix<int>* common_superclasses;

public:
	cbr_ContextModel() : num_concepts(0), concepts(0), concepts_graph(0)
	{
	}

	~cbr_ContextModel();

	bool parse(std::istream& input);

	int getEdgeWeight(int a, int b) const;

	bool hasConcept(const cbr_Concept& concept) const
	{
		return (concepts_map.find(concept) != concepts_map.end());
	}
	void getSubClasses(const cbr_Concept& concept,
			   cbr_ConceptsSet& set) const;
	void getSuperClasses(const cbr_Concept& concept,
			     cbr_ConceptsSet& set) const;
	int getCommonSuperClassesCount(const cbr_Concept& c1,
				 const cbr_Concept& c2) const;
	cbr_Concept findClosestAtomicConcept(const cbr_Concept& c1,
					const cbr_Concept& c2) const;

	std::set<cbr_ID>* getForwarders(const cbr_ContextAddress& ca,
				const cbr_CRTable& crtable, bool mcast,
				cbr_ID localID) const;

	std::set<cbr_ID>* getForwarders(const cbr_ID id,
				const cbr_CRTable& crtable,
				cbr_ID localID) const;

	std::set<cbr_ID>* getSources(const cbr_CRTable &crtable,
				     cbr_ConceptsSet &cset,
				     cbr_ID localID) const;

	static void joinSets(cbr_ConceptsSet& dst, const cbr_ConceptsSet& src);

private:
	void countCommonSuperClasses();
};

#endif	// cbr_context_model_h_
